package com.alibaba.dubbo.dynamic.utils;

import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Created by wuyu on 2016/8/11.
 */
public class ClassUtils {


    public static List<Class> findClassWithAnno(URL jar, URL[] dependency, List<Class> annos) throws IOException, ClassNotFoundException {
        List<Class> aClass = findClass(jar, dependency);
        List<Class> filterClass = new ArrayList<Class>();
        for (Class clazz : aClass) {
            for (Class ann : annos) {
                if (clazz.getAnnotation(ann) != null && !clazz.isInterface()) {
                    filterClass.add(clazz);
                }
            }
        }
        return filterClass;
    }


    public static List<Class> findClass(URL jar, URL[] dependency) throws IOException, ClassNotFoundException {
        URLClassLoader urlClassLoader = new URLClassLoader(dependency);

        List<String> classNames = findClassName(jar);
        List<Class> classes = new ArrayList<Class>();
        for (String className : classNames) {
            Class<?> aClass = urlClassLoader.loadClass(className);
            classes.add(aClass);
        }

        return classes;
    }

    public static List<String> findClassName(URL jar) throws IOException {
        List<String> classNames = new ArrayList<String>();
        ZipFile zipFile = new ZipFile(jar.getFile());
        ArrayList<? extends ZipEntry> list = Collections.list(zipFile.entries());
        for (ZipEntry en : list) {
            String name = en.getName();
            if (name.lastIndexOf(".class") != -1) {
                name = name.replace("/", ".").replace(".class", "");
                classNames.add(name);
            }
        }
        return classNames;
    }

}
